package com.faxsun.controller.uc.entity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.broadleafcommerce.common.util.TransactionUtils;
import org.broadleafcommerce.profile.core.domain.Customer;
import org.broadleafcommerce.profile.core.service.CustomerService;
import org.broadleafcommerce.profile.web.core.service.login.LoginService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.faxsun.profile.core.domain.FSCustomerImpl;
import com.faxsun.profile.core.domain.FSThirdPartyCustomer;
import com.faxsun.profile.core.service.FSCustomerService;
import com.faxsun.profile.core.service.FSThirdPartyCustomerService;

@Component
public class K360 extends ThirdPartyLoginAbs {
	@Resource(name = "fsThirdPartyService")
	ThirdPartyLoginServer loginServer;

	@Resource(name = "blCustomerService")
	CustomerService customerService;

	@Resource(name = "blLoginService")
	LoginService blLoginService;

	@Resource(name = "blThirdPartyCustomerService")
	FSThirdPartyCustomerService fscustomer3thService;

	private static final Log log = LogFactory.getLog(K360.class);
	private static final String TREASURE_PATH = "redirect:/treasure";
	private static final String TREASURE = "treasure";
	private static final String K360_VERIFY = "http://www.ka360.com.cn/v/verify/";
	private static final String K360_CHANNEL = "0001";

	/**
	 * 发往卡360验证verify code是否有效，有效为1
	 */
	private static final String VERIFYCODE_SUCCESS = "1";

	private String process(String uid, String username, String channelId, String path) {
		log.warn("Process Ka360 uid=" + uid + " username=" + username + " channelId=" + channelId + " path=" + path);
		if (fscustomer3thService.checkCustomerBy3thUid(uid)) {
			Customer customer = fscustomer3thService.getCustomerByUid(uid);
			if (customer != null) {
				// avoid user change username: in K360 username is phone number.
				if (!username.equals(customer.getUsername())) {
					customer.setUsername(username);
				}
				log.warn("Process login for ka360");
				loginServer.loginDirectly(customer);
			}
			if (path != null && path.equals(TREASURE)) {
				return TREASURE_PATH;
			}
			return HOME;
		} else {
			return registerThenLogin(username, uid, channelId, path);
		}
	}

	@Transactional(TransactionUtils.DEFAULT_TRANSACTION_MANAGER)
	private String registerThenLogin(String username, String uid, String channelId, String path) {
		FSCustomerImpl customer = (FSCustomerImpl) customerService.createCustomer();

		customer.setId(customerService.findNextCustomerId());
		customer.setFirstName(username);
		customer.setUsername(username);
		customer.setMobile(username);
		String password = username;
		customer.setVerified(true);
		customer.setIsCustomer3th(true);
		((FSCustomerService) customerService).easyRegisterCustomer(customer, password);

		FSThirdPartyCustomer fsCustomer3th = fscustomer3thService.create3thCustomerByUid(uid);
		fsCustomer3th.setChannelId(channelId);
		fsCustomer3th.setCustomer(customer);
		fscustomer3thService.save(fsCustomer3th);

		blLoginService.loginCustomer(customer);
		if (path != null && path.equals(TREASURE)) {
			return TREASURE_PATH;
		}
		return HOME;
	}

	private String convertStreamToString(InputStream is) {
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder();

		String line = null;
		try {
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb.toString();
	}

	private String checkToken(String resUrl) {
		// 创建HttpClient实例
		CloseableHttpClient httpClient = HttpClients.createDefault();
		// HTTP Get请求(POST雷同)
		HttpGet httpgets = new HttpGet(resUrl);
		CloseableHttpResponse httpResponse = null;
		// 设置请求和传输超时时间
		Integer timeOut = 3000; // 3 秒 超时
		RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(timeOut)
				.setConnectTimeout(timeOut).setSocketTimeout(timeOut).build();
		httpgets.setConfig(requestConfig);
		HttpEntity entity = null;
		try {
			httpResponse = httpClient.execute(httpgets);
			entity = httpResponse.getEntity();
			if (entity != null) {
				InputStream instreams = entity.getContent();
				String str = convertStreamToString(instreams);
				log.warn(str);
				httpgets.abort();
				int index = str.indexOf(':');
				if (index != -1) {
					return str.substring(index + 1, index + 2);
				}
			}
		} catch (ClientProtocolException e) {
			log.error("http protocol error：" + e.getMessage());
		} catch (IOException e) {
			log.error("http IO error：" + e.getMessage());
		} catch (Exception e) {
			log.error("httpException：" + e.getMessage());
		} finally {
			try {
				httpResponse.close();
			} catch (IOException e) {
				log.error("http IO error ：" + e.getMessage());
			} catch (NullPointerException e) {
				log.error("http NullPointer error：" + e.getMessage());
			}
		}
		return null;
	}

	@Override
	public String login(ThirdPartyObj obj) {
		if (obj.getChannelId().equals(K360_CHANNEL)) {
			String resUrl = K360_VERIFY + obj.getAccessToken();
			String result = checkToken(resUrl);
			if (result != null) {
				// 卡360返回结果为1，为验证成果，切务修改
				return process(obj.getUid(), obj.getNickName(), obj.getChannelId(), obj.getPATH());
			}
		}
		return HOME;
	}

	@Override
	public ThirdPartyObj get3rdObj(HttpServletRequest request, HttpServletResponse response, String channel,
			String path) {
		ThirdPartyObj obj3rd = new ThirdPartyObj();
		String channelId = request.getParameter("channelId");
		String uid = request.getParameter("uId");
		String nickName = request.getParameter("mobile");
		String accessToken = request.getParameter("token");

		if (channelId == null || uid == null || nickName == null || accessToken == null) {
			try {
				request.getRequestDispatcher("/").forward(request, response);
			} catch (ServletException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		obj3rd.setChannelId(channel);
		obj3rd.setPATH(path);
		obj3rd.setUid(uid);
		obj3rd.setNickName(nickName);
		obj3rd.setAccessToken(accessToken);

		return obj3rd;
	}

	// No use in K360
	@Override
	public void ResponseURL(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub

	}

}
